﻿using DevelopTool.Bll.LocalDbBlls;
using DevelopTool.Common;
using DevelopTool.Model.CommonModels;
using DevelopTool.Model.DbModels;
using DevelopTool.Model.Enums;
using LiteDB;
using System;
using System.Collections.Generic;
using System.Linq;

namespace DevelopTool.Bll.DbBlls
{
    /// <summary>
    /// 数据库连接信息业务
    /// </summary>
    public class DbInfoBll : BaseBll
    {

        public DbInfoBll()
        {
            using (var db = new LiteDatabase(LiteDbContext.ConnectionString))
            {
                var col = db.GetCollection<DbInfo>();
                col.EnsureIndex(x => x.NodeName);
                col.EnsureIndex(x => x.DbType);
                col.EnsureIndex(x => x.CreateTime);
                col.EnsureIndex(x => x.Id);
            }
        }

        /// <summary>
        /// 根据数据库连接字符串获取DbInfo对象
        /// </summary>
        /// <param name="connectionString"></param>
        /// <returns></returns>
        public DbInfo GetDbInfoByConnectionString(string connectionString)
        {
            if (string.IsNullOrEmpty(connectionString)) return null;

            DbInfo dbInfo = new DbInfo();

            var strs = connectionString.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries);
            foreach (string str in strs)
            {
                if (str.ToUpper().Contains("Data Source=".ToUpper())) dbInfo.Ip = (str + ";").GetContent("Data Source=", ";", 2);
                if (str.ToUpper().Contains("User ID=".ToUpper())) dbInfo.UserName = (str + ";").GetContent("User ID=", ";", 2);
                if (str.ToUpper().Contains("Password=".ToUpper())) dbInfo.Password = (str + ";").GetContent("Password=", ";", 2);
            }

            return dbInfo;
        }

        /// <summary>
        /// 获取列表
        /// </summary>
        /// <returns></returns>
        public List<DbInfo> GetList(DbType dbType = DbType.Unknown)
        {
            using (var db = new LiteDatabase(LiteDbContext.ConnectionString))
            {
                var models = db.GetCollection<DbInfo>().FindAll();

                if (dbType != DbType.Unknown)
                {
                    models = models.Where(it => it.DbType == dbType);
                }

                return models.OrderByDescending(it => it.CreateTime).ToList();
            }
        }


        /// <summary>
        /// 根据连接内容关键字查询到连接id集合
        /// </summary>
        /// <param name="text"></param>
        /// <returns></returns>
        public List<DbInfo> GetListByContent(string text)
        {
            using (var db = new LiteDatabase(LiteDbContext.ConnectionString))
            {
                List<DbInfo> resultList = new List<DbInfo>();

                var col = db.GetCollection<DbInfo>();

                var idList = col.Find(it => !string.IsNullOrEmpty(it.Ip) && it.Ip.IndexOf(text, StringComparison.OrdinalIgnoreCase) > -1).Select(it => it.Id).ToList();
                var list2 = col.Find(it => !string.IsNullOrEmpty(it.UserName) && it.UserName.IndexOf(text, StringComparison.OrdinalIgnoreCase) > -1).Select(it => it.Id).ToList();
                var list3 = col.Find(it => !string.IsNullOrEmpty(it.Password) && it.Password.IndexOf(text, StringComparison.OrdinalIgnoreCase) > -1).Select(it => it.Id).ToList();
                var list4 = col.Find(it => !string.IsNullOrEmpty(it.Port) && it.Port.IndexOf(text, StringComparison.OrdinalIgnoreCase) > -1).Select(it => it.Id).ToList();
                var list5 = col.Find(it => !string.IsNullOrEmpty(it.ConnectionString) && it.ConnectionString.IndexOf(text, StringComparison.OrdinalIgnoreCase) > -1).Select(it => it.Id).ToList();
                var list6 = col.Find(it => !string.IsNullOrEmpty(it.Remark) && it.Remark.IndexOf(text, StringComparison.OrdinalIgnoreCase) > -1).Select(it => it.Id).ToList();
                idList.AddRange(list2);
                idList.AddRange(list3);
                idList.AddRange(list4);
                idList.AddRange(list5);
                idList.AddRange(list6);

                foreach (int id in idList)
                {
                    if (resultList.Exists(it => it.Id == id)) continue;//不重复插入

                    resultList.Add(col.FindOne(it => it.Id == id && it.NodeType == MenuNodeType.Node));//只查询节点，不要目录
                }

                return resultList;
            }
        }


        /// <summary>
        /// 根据id获对象
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public DbInfo GetById(int id)
        {
            using (var db = new LiteDatabase(LiteDbContext.ConnectionString))
            {
                var col = db.GetCollection<DbInfo>();

                return col.FindById(id);
            }
        }


        /// <summary>
        /// 保存
        /// </summary>
        /// <param name="dbInfo"></param>
        /// <returns></returns>
        public DbInfo Save(DbInfo dbInfo)
        {
            using (var db = new LiteDatabase(LiteDbContext.ConnectionString))
            {
                var col = db.GetCollection<DbInfo>();
                dbInfo.UpdateTime = DateTime.Now;
                col.Upsert(dbInfo);

                return col.FindById(dbInfo.Id);
            }
        }


        /// <summary>
        /// 删除
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public bool Delete(int id)
        {
            using (var db = new LiteDatabase(LiteDbContext.ConnectionString))
            {
                var col = db.GetCollection<DbInfo>();

                //查询是否有子节点，若有子节点，则不删除。
                if (col.Exists(it => it.NodePid == id)) return false;

                var groupCol = db.GetCollection<DbSourceGroup>();

                var group = groupCol.FindOne(it => it.DbInfo.Id == id && it.NodePid == 0 && it.NodeType == MenuNodeType.Folder);

                if (group != null)
                {
                    new DbSourceGroupBll().DeleteAll(group.Id);//删除所有相关的资源分组数据

                    groupCol.Delete(group.Id);//删除资源分组
                }

                return col.Delete(id);
            }
        }



        public void SetRemark(int id, string remark)
        {
            using (var db = new LiteDatabase(LiteDbContext.ConnectionString))
            {
                var col = db.GetCollection<DbInfo>();

                var model = col.FindOne(it => it.Id == id);

                model.Remark = remark;
                model.UpdateTime = DateTime.Now;

                col.Update(model);
            }
        }

        public ManageMenu Get(int id)
        {
            using (var db = new LiteDatabase(LiteDbContext.ConnectionString))
            {
                return db.GetCollection<DbInfo>().FindOne(it => it.Id == id);
            }
        }

    }

}
